package main

import (
	"encoding/json"
	"fmt"
	"fyne.io/fyne"
	"io/ioutil"
	"log"
	"strings"

	"fyne.io/fyne/app"

	"fyne.io/fyne/widget"
	"github.com/flopp/go-findfont"
	"os"

	"fyne.io/fyne/layout"
	"github.com/scchenyong/sshtunnel/sstunnel"
)

type diagonal struct {

}

type Ui struct {
	remoteEntry *widget.Entry
	r_portEntry *widget.Entry
	targetEntry *widget.Entry
	t_portEntry*widget.Entry
	l_portEntry *widget.Entry

	User*widget.Entry
	password *widget.Entry

	output *widget.Label

	startBtn *widget.Button
	saveBtn *widget.Button

}

func (ui *Ui)listen()  {

}



func (ui *Ui)stop(){
	ui.startBtn.SetText("start")
	tunel.Close()
}


func (ui *Ui)start() {

	st := &sshtunnel.Config{
		Addr:    fmt.Sprintf("%s:%s",ui.remoteEntry.Text,ui.r_portEntry.Text),
		User:    ui.User.Text,
		Pass:    ui.password.Text,
		Tunnels: []sshtunnel.Tunnel{{
			Remote: fmt.Sprintf("%s:%s",ui.targetEntry.Text,ui.t_portEntry.Text),
			Local:  fmt.Sprintf("%s:%s","0.0.0.0",ui.l_portEntry.Text),
		}},
	}



	tu := sshtunnel.NewSSHTunnel(st)
	tunel = tu
	go 	tu.Start(channel)
	ui.outputLabel("ssh -p "+ui.l_portEntry.Text + " 127.0.0.1 连接目标服务器")
	ui.startBtn.SetText("停止")



}

func (ui *Ui)LoadConfig()  {
	 ssh := config()
	if strings.ContainsAny(ssh.Addr,":") {
		s :=strings.Split(ssh.Addr,":")
		ui.remoteEntry.SetText(s[0])
		ui.r_portEntry.SetText(s[1])
	}
	if ssh.User != "" {
		ui.User.SetText(ssh.User)
	}
	if ssh.Pass != "" {
		ui.password.SetText(ssh.Pass)
	}
	if len(ssh.Tunnels) >0  {
		tu := ssh.Tunnels[0]
		if strings.Contains(tu.Remote,":"){
			s :=strings.Split(tu.Remote,":")
			ui.targetEntry.SetText(s[0])
			ui.t_portEntry.SetText(s[1])
		}
		if strings.Contains(tu.Local,":"){
			s :=strings.Split(tu.Local,":")
			ui.l_portEntry.SetText(s[1])
		}else {
			ui.l_portEntry.SetText("8888")
		}
	}



}

func (ui *Ui)saveConfig()  {
	st := &sshtunnel.Config{
		Addr:    fmt.Sprintf("%s:%s",ui.remoteEntry.Text,ui.r_portEntry.Text),
		User:    ui.User.Text,
		Pass:    ui.password.Text,
		Tunnels: []sshtunnel.Tunnel{{
			Remote: fmt.Sprintf("%s:%s",ui.targetEntry.Text,ui.t_portEntry.Text),
			Local:  fmt.Sprintf("%s:%s","0.0.0.0",ui.l_portEntry.Text),
		}},
	}

 	 data,_:=	json.Marshal([]sshtunnel.Config{*st})
	p := "config.json"

	f, err := os.OpenFile(p,os.O_RDWR | os.O_CREATE,0777)
	if err != nil {
		ui.outputLabel(fmt.Sprintf("打开文件失败：%s",err.Error()))
		return
	}
	f.Truncate(0)
	f.Write(data)

}

func (ui *Ui)outputLabel(c string)  {
	tx := ui.output.Text
	tx1 :=fmt.Sprintf("%s\n%s",tx,c)


	ui.output.SetText(tx1)
	ui.output.Refresh()
}


func initFont() {
	fontPaths := findfont.List()
	for _, path := range fontPaths {
		fmt.Println(path)
		//楷体:simkai.ttf
		//黑体:simhei.ttf
		if strings.Contains(path, "Songti.ttc") {
			os.Setenv("FYNE_FONT", path)

			break
		}
	}
	fmt.Println("=============")
}

func ontap()  {
	tx := ui.startBtn.Text

	if  tx == "停止"{
		go ui.stop()
	}else {
		go ui.start()
	}

}
var ui *Ui
var channel chan  string
var tunel *sshtunnel.SSHTunnel
func init()  {
	initFont()
	entry := widget.NewEntry()
	entry2 := widget.NewEntry()
	entry3 := widget.NewEntry()
	entry4 := widget.NewEntry()
	entry5 := widget.NewEntry()
	entry6 := widget.NewEntry()
	entry7 := widget.NewEntry()
	btn1 := widget.NewButton("保存设置到本地", func() {
		ui.saveConfig()
	})
	btn2 := widget.NewButton("启动", ontap)
	out := widget.NewLabel("")
	ui = &Ui{entry,entry2,entry3,entry4,entry5,entry6,entry7,out,btn2,btn1}





}


func config()sshtunnel.Config  {
		var sts []*sshtunnel.Config
		p := "config.json"
		if len(os.Args) == 2 {
			p = os.Args[1]
		}
		f, err := ioutil.ReadFile(p)
		if err != nil {
			log.Printf("载入配置文件出错, 错误: %v", err)
			return sshtunnel.Config{}
		}
		err = json.Unmarshal(f, &sts)
		if nil != err {
			log.Printf("解析配置文件内容出错, 错误: %v", err)

			return sshtunnel.Config{}
		}
	return *sts[0]
}


func main()  {

	defer  os.Unsetenv("FYNE_FONT")

	channel = make(chan string,10)
	go func() {
		for {
			select {
			case c := <- channel:
				fmt.Println(c)
				ui.outputLabel(c)
			}
		}

	}()


	a := app.New()
	w := a.NewWindow("SSH隧道端口转发")

	boxT := widget.NewGroup("目标主机",
		widget.NewForm(widget.NewFormItem("IP：",ui.targetEntry),
				widget.NewFormItem("端口：",ui.t_portEntry),
			),
	)

	boxV := widget.NewGroup("外网主机",
		widget.NewForm(widget.NewFormItem("IP：",ui.remoteEntry),
				widget.NewFormItem("端口：",ui.r_portEntry),
				widget.NewFormItem("SSH 用户名：",ui.User),
				widget.NewFormItem("SSH 密码：",ui.password),
				),
	)

	text := ui.output
	boxB := widget.NewHSplitContainer(
		ui.saveBtn,	ui.startBtn,
	)

	w.SetContent(widget.NewVBox(
		boxT,
		boxV,
		widget.NewGroup("本地端口映射",
			widget.NewHBox(widget.NewLabel("端口"),ui.l_portEntry),
		),
		boxB,
		fyne.NewContainerWithLayout(layout.NewGridWrapLayout(fyne.Size{Height:300,Width:600}),widget.NewVScrollContainer(text),), ))
	ui.LoadConfig()
	ui.outputLabel("ssh -p "+ui.l_portEntry.Text + " 127.0.0.1 连接目标服务器")
	w.Resize(fyne.Size{600,400})


	w.ShowAndRun()

}